<?php

/*
 * Table/EmployeTable.php
 */

namespace RHX\Model\Table;

use Zend\Db\TableGateway\AbstractTableGateway;
use Zend\Db\Adapter\Adapter;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\Sql\Select;
use Zend\Db\Sql\Where;
use RHX\Model\Object\Employe;
use Zend\Db\Sql\Predicate;

class EmployeTable extends AbstractTableGateway {

    /**
     *
     * @var string Nom de la table
     */
    protected $table = 'rh_employe';

    /**
     * Constructeur
     *
     * @param \Zend\Db\Adapter\Adapter $adapter
     */
    public function __construct(Adapter $adapter) {
	$this->adapter			 = $adapter;
	$this->resultSetPrototype	 = new ResultSet();
	$this->resultSetPrototype->setArrayObjectPrototype(new Employe($adapter));
	$this->initialize();
    }

    /**
     * Récupérer tous les employés
     *
     * @param type $order
     * @param type $actif
     * @return type
     */
    public function getAll($order = 'matricule ASC', $actif = true) {
	return $this->select(function(Select $select) use($order, $actif) {
			    $select->order($order);
			    $where	 = new Where();
			    $val	 = 1;
			    if (!$actif)
				$val	 = 0;
			    $where->equalTo('actif', $val);
			    $select->order("ancien ASC");
			    $select->order("indice DESC");
			    $select->where($where);
			});
    }

    /**
     * Récupérer tous les employés Paginé
     *
     * @param type $order
     * @param type $page
     * @param type $perPage
     * @return type
     */
    public function getEmployes($order = 'matricule ASC', $page = 1, $perPage = 30, $actif = true) {
	return $this->select(function(Select $select) use($order, $page, $perPage, $actif) {
			    $select->order($order);
			    $offset	 = ($page - 1) * $perPage;
			    $select->offset($offset);
			    $select->limit($perPage);
			    $where	 = new Where();
			    $val	 = 1;
			    if (!$actif)
				$val	 = 0;
			    $where->equalTo('actif', $val);
			    $select->order('ancien ASC');
			    $select->order('indice DESC');
			    $select->where($where);
			});
    }

    /**
     * Récupérer tous les employés d'un Site (paginé)
     *
     * @param type $siteId
     * @param type $order
     * @param type $page
     * @param type $perPage
     * @param type $actif
     * @return ResultSet
     */
    public function getEmployesBySite($siteId, $order = 'matricule ASC', $page = 1, $perPage = 30, $actif = true) {
        return $this->select(function(Select $select) use($siteId, $order, $page, $perPage, $actif) {
                $aOrder = explode(' ', $order);
                
                $select->order($order);
                $offset  = ($page - 1) * $perPage;
                $select->offset((int) $offset);
                $select->limit((int) $perPage);

                                     $where  = new Where();
                $where->equalTo('site_id', $siteId);
                $val  = 1;
                if (!$actif) {
                    $val = 0;
                    //echo '<pre>' . $val . '</pre>';
                }
                $where->equalTo('actif', $val);
                $where->equalTo('ancien', 0);
                $select->order('ancien ASC');
                $select->order('indice DESC');
                $select->where($where);
		//echo '<pre>' .@$select->getSqlString() .'</pre>';
            });
    }

    /* Récupérer tous les employés d'un Site eventuellement ordonnée par le rang d'un poste
     * oblsolete depuis 27 11 2013 (@author :Fred)
     * getEmployesBySiteEx2 est la plus à jour
     * @param type $siteId
     * @param string $order 
     * @param type $actif
     * 
     * @return ResultSet
     */
    
    public function getEmployesBySiteEx($siteId, $order = 'matricule ASC', $actif = true) {
        return $this->select(function(Select $select) use($siteId, $order, $actif ) {
                $aOrder = explode(' ', $order);
                $joinPoste  = (strtolower($aOrder[0]) === 'poste_rang') ;
                
                if($joinPoste){
                    $select->join('rh_avenant', 'avenant_id = rh_avenant.id');
                    $select->join('rh_poste', 'rh_avenant.poste_id = rh_poste.id');
                }
                
                $where  = new Where();
                $where->equalTo('site_id', $siteId);                
                $val  = 1;
                if (!$actif) { $val = 0;                
                }
                $where->equalTo('actif', $val);
                $where->equalTo('ancien', 0);
                
                if($joinPoste)
                    $select->order('rh_poste.rang '. $aOrder[1]);                
                else
                    $select->order($order);                
                
                $select->order('ancien ASC');
                $select->order('indice DESC');
                $select->where($where);
            });
    }
    
    /* Récupérer tous les employés d'un Site eventuellement ordonnée par le rang d'un poste
     * @param type $siteId
     * @param string $order 
     * @param type $actif
     * 
     * @return ResultSet
     * @author : Fred
     */
    
    public function getEmployesBySiteEx2($siteId, $order = 'matricule ASC', $actif = true) {
        return $this->select(function(Select $select) use($siteId, $order, $actif ) {
                // manage order if eventually by poste rang
                $aOrder    = explode(',', $order);
                
                $newOrder = array();
                foreach ($aOrder as $o): 
                    $o = trim($o);
                    $aOrder2 = explode(' ', $o);
                    
                    if(strtolower(trim($aOrder2[0])) === 'poste_rang'){
                        $joinPoste  =  true;
                        $newOrder[] = 'rh_poste.rang' . ' ' . $aOrder2[1];                        
                    }
                    else{
                        $newOrder[] = $o;
                    }
                endforeach;
                $newOrder = implode(', ', $newOrder) ; 
                // end manage order
                
                if(isset($joinPoste) && $joinPoste){
                    $select->join('rh_avenant', 'avenant_id = rh_avenant.id');
                    $select->join('rh_poste', 'rh_avenant.poste_id = rh_poste.id');
                }
                
                $where  = new Where();
                $where->equalTo('site_id', $siteId);                
                $val  = 1;
                if (!$actif) { $val = 0;                
                }
                $where->equalTo('actif', $val);
                //$where->equalTo('ancien', 0);
                
                /*
                if($joinPoste)
                    $select->order('rh_poste.rang '. $aOrder[1]);                
                else
                    $select->order($order);   
                 */             
                $select->order($newOrder);   
                
                $select->order('ancien ASC');
                $select->order('indice DESC');
                $select->where($where);
            });
    }
    
      /**
     * Récupérer le nombre des employés d'un Site selon eventuellement les critères de recherche en param ( pagination )
     * Doit être coherent avec la methode "getCountEmployesByCriteria()"
     * 
     * @param int $siteId
     * @param int $actif
     * @param int $page
     * @param int $perPage
     * @param String $nom 
     * @param int $contratType 
     * @param int $poste
     * @return ResultSet
     * @author Fréd
     */

    public function getEmployesByCriteria($siteId, $order = 'matricule ASC', $page = 1, $perPage = 30, $actif = true, $nom=null, $contratType = null, $poste = null) {
        
        $sql = "SELECT * FROM rh_employe ";
        
        /* begin jointure */
        $hasJoin = $poste > -1;
        if($hasJoin){
            $sql .= " JOIN rh_avenant ON avenant_id = rh_avenant.id ";
        }
        /* end jointure*/
        
        /*begin where*/
        $sql  .= " WHERE 1 = 1 ";          
        
        if($siteId > -1)
            $sql  .= " AND site_id = " . $siteId . " ";          
        
        $val	 = 1;
        if (!$actif) {
            $val = 0;            
        }
        if($actif != -1){ // si 0 seulement actif ou inactif
            $sql .= " AND actif = $val " ;
        }
        
        if($contratType)
            $sql .= " AND contrat_type LIKE  '%$contratType%' " ;           
        
        if($hasJoin)
            $sql .= " AND  rh_avenant.poste_id =  $poste " ;
            
        if($nom){            
            $clauseNom = '';
            $arrayNames = explode(' ', $nom);

            foreach ($arrayNames as $k => $name ){
                $cond = $k == 0? '': 'OR';
                $clauseNom .= "$cond nom1 LIKE '%$name%' " ;
                $clauseNom .= "OR prenom LIKE '%$name%' ";
            }
            //var_dump($clauseNom);
            $sql .= ' AND ('.  $clauseNom . ' ) ';
        }
        
         /*end  where*/
        
        $sql  .= " ORDER BY $order ";
        $offset	 = ($page - 1) * $perPage;
        $sql  .= " LIMIT " .(int) $perPage  . " OFFSET  " . (int) $offset . " ";
        
        //var_dump($sql);
        
        $query = $this->getAdapter()->query($sql);
        $result = $query->execute();
        
        $employes = array();
        foreach($result as $row){
            $e = new Employe($this->adapter, $row);
            $employes[] = $e;
        }
        return $employes;
    }
    
    /**
     * Récupérer le nombre des employés d'un Site selon eventuellement les critère de recherche en param     
     * Doit être coherent avec la methode "getEmployesByCriteria()"
     * 
     * @param int $siteId
     * @param int $actif
     * @param String $nom 
     * @param int $contratType 
     * @param int $poste
     * @return ResultSet
     * @author Fréd
     */

    public function getCountEmployesByCriteria($siteId, $actif = true, $nom=null, $contratType = null, $poste = null) {
	$sql = "SELECT COUNT(*) AS NumberOfEmploye FROM rh_employe ";
        
        /* begin jointure */
        $hasJoin = $poste > -1;
        if($hasJoin){
            $sql .= " JOIN rh_avenant ON avenant_id = rh_avenant.id ";
        }
        /* end jointure*/
        
        /*begin where*/        
        $sql  .= " WHERE 1 = 1 ";          
        
        if($siteId > -1)
            $sql  .= " AND site_id = " . $siteId . " "; 
        
        
        $val	 = 1;
        if (!$actif) {
            $val = 0;            
        }
        if($actif != -1){ // si 0 seulement actif ou inactif
            $sql .= " AND actif = $val " ;
        }
        
        if($contratType)
            $sql .= " AND contrat_type LIKE  '%$contratType%' " ;           
        
        if($hasJoin)
            $sql .= " AND  rh_avenant.poste_id =  $poste " ;
        
        if($nom){
            $clauseNom = '';
            $arrayNames = explode(' ', $nom);

            foreach ($arrayNames as $k => $name ){
                //$name = mysql_real_escape_string($name);
                
                $cond = $k == 0? '': 'OR';
                $clauseNom .= "$cond nom1 LIKE '%$name%' " ;
                $clauseNom .= "OR prenom LIKE '%$name%' ";
            }
            //var_dump($clauseNom);
            $sql .= ' AND ('.  $clauseNom . ' ) ';
        }
        
    /*end  where*/
        
        $statement = $this->adapter->query($sql);
        $result =  $statement->execute();
        $current = $result->current();
        
        $count = $current['NumberOfEmploye'];
        return (int) $count;
        
    }
    
    /*Recupérer les employé dont les postes ont le libellé specifié
     * 
     * @param String $lib libellé du poste
     */
    
    public function getByPoste($lib, $idSite) {
        return $this->select(function(Select $select) use($lib, $idSite) {
                
                $select->join('rh_avenant', 'rh_employe.avenant_id = rh_avenant.id');
                $select->join('rh_poste', 'rh_avenant.poste_id = rh_poste.id');
                
                $where  = new Where();
                $where->equalTo('site_id', $idSite);                
                
                $where->like('rh_poste.libelle', '%directeur%');                        
                $where->equalTo('actif', 1);
                
                $select->where($where);
                $select->order("rh_poste.rang ASC");
            });
    }
    
    /**
     * Retourne le nombre de page possible pour le nombre par page donnée
     *
     * @param int $siteId
     * @param int $perPage
     * @param boolean $actif
     * @return type
     */
    public function getPageCount($siteId, $perPage = 30, $actif = true) {
	$sql	 = new \Zend\Db\Sql\Sql($this->adapter);
	$select	 = $sql->select();
	$select->from($this->table);
	$select->columns(array(
	    'total' => new \Zend\Db\Sql\Expression("COUNT(matricule)"),
	));
	$where	 = new Where();
	$where->equalTo('site_id', $siteId);
	$where->equalTo('actif', ($actif) ? 1 : 0);
	$select->where($where);
	$state	 = $sql->prepareStatementForSqlObject($select);
	$result	 = $state->execute();
	$current = $result->current();
	$total	 = (int) $current['total'];
	$nbPage	 = (int) ($total / $perPage);
	if ($nbPage * $perPage != $total)
	    $nbPage++;

	return $nbPage;
    }

    /**
     * Récupérer un Employé
     *
     * @param type $matricule
     * @return Employe
     * @throws \Exception
     */
    public function get($matricule) {
	$row = $this->select(array('matricule' => $matricule))
		->current();
	if (!$row)
	    throw new \Exception("Erreur 71 : L'employé au matricule #$matricule n'a pas été trouvé");

	return $row;
    }

    /**
     * Effacer Totalement un employé
     *
     * @param type $matricule
     * @return type
     */
    public function erase($matricule) {
	return $this->delete(array('matricule' => $matricule));
    }

    /**
     * Licencier un Employé
     *
     * @param type $matricule
     */
    public function fire($matricule) {
	$emp		 = $this->get($matricule);
	$emp->actif	 = 0;
	$this->save($emp);
    }

    /**
     * Réembaucher un employé
     *
     * @param type $matricule
     */
    public function hire($matricule) {
	$emp		 = $this->get($matricule);
	$emp->actif	 = 1;
	$this->save($emp);
    }

    /**
     * Sauvegarder les données d'un Employé
     *
     * @param \RHX\Model\Object\Employe $emp
     * @return type
     * @throws \Exception
     */
    public function save(Employe $emp) {
	$data		 = array(
	    'site_id'		 => $emp->site_id,
	    'nom1'			 => $emp->nom1,
	    'nom2'			 => $emp->nom2,
	    'prenom'		 => $emp->prenom,
	    'telephone'		 => $emp->telephone,
	    'email'			 => $emp->email,
	    'contrat_debut'		 => $emp->contrat_debut,
	    'contrat_fin'		 => $emp->contrat_fin,
	    'contrat_type'		 => $emp->contrat_type,
	    'contrat_motif_depart'	 => $emp->contrat_motif_depart,
            'contrat_file'	 => $emp->contrat_file,
	    'avenant_id'		 => $emp->avenant_id,
	    'civil_id'		 => $emp->civil_id,
	    'situation_id'		 => $emp->situation_id,
	    'enfant'		 => $emp->enfant,
	    'naissance'		 => $emp->naissance,
	    'naissance_lieu'	 => $emp->naissance_lieu,
	    'naissance_pays'	 => $emp->naissance_pays,
	    'nationalite_id'	 => $emp->nationalite_id,
	    'adresse1'		 => $emp->adresse1,
	    'cp1'			 => $emp->cp1,
	    'ville1'		 => $emp->ville1,
	    'adresse2'		 => $emp->adresse2,
	    'cp2'			 => $emp->cp2,
	    'ville2'		 => $emp->ville2,
	    'sejour_id'		 => $emp->sejour_id,
	    'sejour_num'		 => $emp->sejour_num,
            'sejour_num_file'		 => $emp->sejour_num_file,
	    'sejour_fin'		 => $emp->sejour_fin,
	    'cpam'			 => $emp->cpam,
	    'pole_emploi'		 => $emp->pole_emploi,
	    'mutuelle'		 => $emp->mutuelle,
	    'mutuelle_date_effet'	 => $emp->mutuelle_date_effet,
	    'rib'			 => $emp->rib,
            'rib_bic'			 => $emp->rib_bic,
            'rib_iban'			 => $emp->rib_iban,
	    'transport_id'		 => $emp->transport_id,
	    'vehicule'		 => $emp->vehicule,
	    'immatriculation'	 => $emp->immatriculation,
	    'num_permis'		 => $emp->num_permis,
	    'code_caisse_tcpos'	 => $emp->code_caisse_tcpos,
	    'cv_path'		 => $emp->cv_path,
	    'photo'			 => $emp->photo,
	    'actif'			 => $emp->actif,
	    'ancien'		 => $emp->ancien,
	    'indice'		 => $emp->indice,
            'transfert'		 => $emp->transfert,
	);
	$matricule	 = (int) $emp->matricule;
	if ($matricule == 0) {
	    $this->insert($data);

	    return $this->lastInsertValue;
	}
	elseif ($this->get($matricule)) {
	    $this->update($data, array('matricule' => $matricule));

	    return $matricule;
	}
	else {
	    throw new \Exception("Erreur 72 : L'Employé matricule #$matricule n'a pas été sélectionner pour une mise à jour");
	}
    }

    public function executeQuery($sql) {
	return $this->adapter
			->query($sql)
			->execute();
    }
    /*
     * 
     * 
     */
    public function getEmployesByTaux($taux){	
	$sql = "SELECT matricule FROM rh_employe e
		JOIN rh_avenant a ON e.avenant_id = a.id
		WHERE a.taux = $taux" ;
	
	$query = $this->getAdapter()->query($sql);	
	$result = $query->execute();
        
        $employes = array();	
        foreach($result as $row){
	    $e = $this->get((int) $row['matricule']) ;	   
	    $employes[] = $e;
        }
	
        return $employes;
    }
    
    /* recupère un Employé par un avenant id
     * @return Employe
     */
    public function getOneByAvenant($avenantId){
        $row = $this->select(array('avenant_id' => $avenantId))
		->current();
	if (!$row)
	    throw new \Exception("Erreur 71 : L'employé possedant l'avenant #$avenantID n'a pas été trouvé");

	return $row;
    }
    
     /* recupère un Employé par el champ transfert
      * @param int $transfert
      * @return Employe
      */
    public function getOneByTransfert($transfert){
        $row = $this->select(array('transfert' => $transfert))
		->current();
	if (!$row)
	    throw new \Exception("Erreur  : L'employé dont avec transfert #$transfert n'a pas été trouvé");

	return $row;
    }

}

?>
